按照順序,存放多個相同型態資料的容器。
與上一張結構的容器概念不一樣的是,結構沒有順序性,且存放的可以是各種資料型態。
大多數的程式語言中,有一個稱為陣列的東西,它可以用一個變數名稱代替多個變數值。
當然 Go 也有,但是它有幾個限制:
基本長這樣:
:::info
[長度]資料型態
:::
var arr [4]int
// 陣列[編號]代表陣列中的一個資料欄位
fmt.Println(arr[2])
先宣告變數 arr 的資料型態是長度為 4 的整數陣列。
印出陣列中 index 為 2 的資料。
![](https://i.imgur.com/GWtUuD0.png =300x)
跟 Ruby 一樣,index 從 0 開始算起。
接下來會針對建立陣列、給定資料、巡迴陣列。
在 Go 中是這樣宣告陣列的:
var arr1 [4]int
var arr2 [2]string
var arr3 [3]bool
宣告 arr1 為長度為 4 的整數陣列。
宣告 arr2 為長度為 2 的字串陣列。
宣告 arr3 為長度為 3 的布林陣列。
可以在宣告陣列變數的同時給定一個初始的陣列資料。
如果沒有給初始陣列資料,Go 會自動給定資料型態的初始值,例如:int 就會是 [0 0 0 0]、string 就會是 [ ] ...。
在 Go 是這樣宣告陣列變數及給定陣列資料:
var arr1 [4]int = [4]int{3, 10, -2, 0}
var arr1 [2]string = [2]string{"Hello", "World"}
var arr1 [3]bool = [3]bool{true, false, true}
:::warning
如果宣告時是給int 那資料就必須是 int;是 string 就必須是 string。
而且數量也必須要相同,數量是 4 就必須是 4。
:::
我們也可以省略宣告變數型態,因為編譯器可以從初始化的值中推斷出型別。如果使用這種方式,則必須要給出陣列的長度。
package main
import "fmt"
func main(){
var fruit = [6]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
fmt.Println(fruit[2])
}
執行結果:
lemon
我們也可以用換行的寫法:
package main
import "fmt"
func main(){
fruit := [6]string{
"apple",
"banana",
"lemon",
"pineapple",
"watermelon",
"onange",
}
fmt.Println(fruit[4])
}
執行結果:
watermelon
但是這邊要記得在結尾加上 ,
,如果不加會發生編譯錯誤的訊息。
如果你懶的話,也可以這樣寫:
package main
import "fmt"
func main(){
fruit := [6]string{
"apple",
"banana",
"lemon",
"pineapple",
"watermelon",
"onange"}
fmt.Println(fruit[4])
}
執行結果:
watermelon
這樣就不用在最後還要加,
。
題外話:
Go Array 跟 Ruby Array來做比較:
arr1 = [3, 10, -2, 0]
arr2 = ["Hello", "World"]
arr3 = [true, false, true]
# 在 Ruby 中甚至不用在意資料型態
arr4 = [3, "Hi", true]
也可以不用在一開始的時候就給定陣列資料。
在一開始先宣告一個預設的初始值,接著在一個一個給定。如下:
var arr [4]int
arr[0] = 3
arr[1] = 10
arr[2] = -2
arr[3] = 0
package main
import "fmt"
func main(){
var fruit [6]string
fruit[0] = "apple"
fruit[1] = "banana"
fruit[2] = "lemon"
fruit[3] = "pineapple"
fruit[4] = "watermelon"
fruit[5] = "onange"
fmt.Println(fruit[3])
}
執行結果:
pineapple
當然也可以不用全部都給:
package main
import "fmt"
func main(){
var fruit [6]string
fruit[0] = "apple"
fruit[1] = "banana"
fruit[2] = "lemon"
fruit[3] = "pineapple"
fmt.Println(fruit[5])
}
執行結果:
(空無一物)
執行結果會是空無一物,這是上面有提過的,Go 在沒有給定初始資料時,會自動給定資料型態的初始值。
上面的程式碼是字串陣列,所以給的初始值就會是空字串。
這樣有預設值的設計不只出現在陣列,在宣告一般變數沒有給值,Go 會很貼心的給你預設值。
package main
import "fmt"
func main(){
var n int
fmt.Println(n)
}
執行結果:
0
還記得 :=
嗎?在宣告變數時很常用,在宣告陣列時,也可以去使用。
package main
import "fmt"
func main(){
fruit := [6]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
fmt.Println(fruit[2])
}
執行結果:
banana
上面有提到宣告陣列時,要給定陣列長度,但是當遇到很長的陣列時,可以叫 Go 來幫你算。
只要在 []
加上 ...
,這樣 Go 就會幫你算好剛好的長度。
package main
import "fmt"
func main(){
fruit := [...]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
fmt.Println(fruit[5])
}
執行結果:
orange
要怎麼取得陣列的值?
:::info
陣列名稱[index]
:::
這樣就可以取得陣列內指定位置的值。
但有一點要注意,當要求超過陣列長度的值,就會出現錯誤訊息。
package main
import "fmt"
func main(){
fruit := [...]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
fmt.Println(fruit[6])
}
執行結果:
invalid argument: index 6 out of bounds [0:6] (exit status 1)
要怎麼取得陣列長度,在 Go 中,用 len 來取得:
var arr1 [4]int = [4]int{3, 10, -2. 0}
var arr2 [2]string = [2]string{"Hello","World"}
// 利用 len(陣列) 取得陣列長度
fmt.Println(len(arr1)) // 4
fmt.Println(len(arr2)) // 2
在 Go 中,會用 for loop 搭配 Array,去得到 Array 中每一筆資料。
像是 JS 的 forEach,Ruby 的 each。
var arr1 [4]int = [4]int{3, 10, -2, 0}
var index int
for index=0; index < len(arr); index ++{
fmt.Println(arr[index])
}
package main
import "fmt"
func main(){
fruit := [...]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
for i := 0; i < len(fruit); i++{
fmt.Println(fruit[i])
}
}
執行結果:
apple
banana
lemon
pineapple
watermelon
onange
除了用 for loop
還可以用 range
。
Go 提供了 range
來走訪陣列,這個方法可以用來走訪所有有「迭代器」的資料結構,後面會在解釋「迭代器」是甚麼。
package main
import "fmt"
func main(){
fruit := [...]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
for k, v := range fruit {
fmt.Printf("fruit[%d]: %s\n", k, v)
}
}
執行結果:
fruit[0]: apple
fruit[1]: banana
fruit[2]: lemon
fruit[3]: pineapple
fruit[4]: watermelon
fruit[5]: onange
k 代表的是 key
: 0,1,2,3,4,5
v 代表的是 value
: "apple", "banana", "lemon", "pineapple", "watermelon", "onange"
如果不需要其中一個值,可以用之前學過的 _
去忽略。
package main
import "fmt"
func main(){
fruit := [...]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
for _, v := range fruit {
fmt.Printf("%s\n",v)
}
}
執行結果:
apple
banana
lemon
pineapple
watermelon
onange
另外使用range
巡迴陣列時,直接更改 value
並不會對陣列內的值造成影響,但仍然可以透過 key
去更改。
更改 value:
package main
import "fmt"
func main(){
fruit := [...]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
for _, v := range fruit {
v = v + "!"
fmt.Println(v)
}
for _, v := range fruit {
fmt.Printf("",v)
}
}
執行結果:
apple!
banana!
lemon!
pineapple!
watermelon!
onange!
apple
banana
lemon
pineapple
watermelon
onange
透過 key 更改value:
package main
import "fmt"
func main(){
fruit := [...]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
for k, v := range fruit {
fruit[k] = v + v
}
for _, v := range fruit {
fmt.Println(v)
}
}
執行結果:
appleapple
bananabanana
lemonlemon
pineapplepineapple
watermelonwatermelon
onangeonange
在 Go 中,陣列長度在編譯完後就不能再更動,因此在執行程式前,陣列長度就必需是確定的,變數值是由 Go 發動時才被確定的,所以不能使用變數來設定陣列的長度。Go 的陣列是「很純的陣列」所以才會這樣規定。
package main
import "fmt"
func main(){
length := 6
fruit := [length]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
for _, v := range fruit{
fmt.Println(v)
}
}
執行結果:
invalid array length length (exit status 1)
如果還是希望透過類似的手法來完成,那可以宣告一個常數(constant)
。
package main
import "fmt"
func main(){
const length int = 5
fruit := [length]string{"apple", "banana", "lemon", "pineapple", "watermelon", "onange"}
for _, v := range fruit{
fmt.Println(v)
}
}
執行結果:
apple
banana
lemon
pineapple
watermelon
onange
宣告成常數後就不能更改其值,因為常數能在編譯前確定,所以可以當作陣列的長度。
package main
import "fmt"
func main(){
const length int = 5
length = 7
fmt.Println(length)
}
執行結果:
cannot assign to length (constant 5 of type int) (exit status 1)
func main() {
// 整數陣列
var numbers [4]int
numbers[0] = 13
numbers[1] = 111
numbers[2] = 23
numbers[3] = 92
fmt.Println(numbers) // 印出 [13 111 23 92]
}
如果多給一個會怎樣?
func main() {
// 整數陣列
var numbers [4]int
numbers[0] = 13
numbers[1] = 111
numbers[2] = 23
numbers[3] = 92
numbers[4] = 22
fmt.Println(numbers)
}
$ go build array-basic.go
# command-line-arguments
./array-basic.go:12:10: invalid argument: index 4 out of bounds [0:4]
Go 會不允許這樣建立。
func main(){
var words [2]string
fmt.Println(words)
}
這樣會印出 [ ]。
不要擔心,在 Go 會用空格來做區隔。
所以字串陣列沒給初始值,會長成這樣。
先給定初始資料:
func main(){
var words [2]string = [2]string{"John", "Tom"}
fmt.Println(words) // 印出 [John Tom]
}
計算學生成績總和:
func main(){
var grades [3]int = [3]int{60, 90, 73}
var sum int
var index int
for index = 0; index < len(grades); index++ {
sum = sum + grades[index]
// sum += grades[index]
}
fmt.Println(sum / len(grades))
}
讓使用者自己輸入成績:
func main(){
var grades [4]int
var index int
fmt.Println("請輸入成績")
// 逐一輸入陣列的資料
for index = 0; index < len(grades); index++ {
fmt.Scanln(&grades[index])
}
// 逐一取得陣列資料並計算
var sum int
for index = 0; index < len(grades); index++ {
sum += grades[index]
}
fmt.Println(sum / len(grades))
}